#!/usr/bin/env python3
"""
通用文档信息抽取 - 混合文档数据生成器

该脚本生成用于训练的多种文档类型数据，包括：
1. 文档（25%）
2. 发票文档（25%）
3. 简历文档（20%）
4. 身份证文档（15%）
5. 医疗报告（15%）

支持混合数据集训练，不区分文档类型
"""

import json
import random
from datetime import datetime, timedelta
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
import os
from typing import Dict, List, Any
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 尝试导入模板管理器，容错处理
try:
    from template_manager import get_template_manager
    TEMPLATE_MANAGER_AVAILABLE = True
except ImportError:
    logger.warning("模板管理器不可用，使用内置字段定义")
    TEMPLATE_MANAGER_AVAILABLE = False
    get_template_manager = None


class MixedDocumentGenerator:
    """混合文档数据生成器 - 支持多种文档类型"""
    
    def __init__(self, output_dir: str = "data"):
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(exist_ok=True)
        self.images_dir = self.output_dir / "images"
        self.images_dir.mkdir(exist_ok=True)
        
        # 文档类型分布比例
        self.document_types = {
            'contract': 0.25,      #  25%
            'invoice': 0.25,       # 发票 25%
            'resume': 0.20,        # 简历 20%
            'id_card': 0.15,       # 身份证 15%
            'medical_report': 0.15 # 医疗报告 15%
        }
        
        # 加载字体配置
        self.font_config = self._load_font_config()
        
        # 初始化文档模板字段
        self._init_document_fields()
        
        # 初始化所有文档类型的数据模板
        self._init_document_templates()
        
    def _init_document_fields(self):
        """初始化文档字段定义"""
        self.document_fields = {}
        
        if TEMPLATE_MANAGER_AVAILABLE:
            try:
                manager = get_template_manager()
                for doc_type in self.document_types.keys():
                    template = manager.get_template(doc_type)
                    if template:
                        self.document_fields[doc_type] = template.get_field_names()
                        logger.info(f"✅ 加载{doc_type}字段: {len(self.document_fields[doc_type])}个")
                    else:
                        logger.warning(f"⚠️  未找到{doc_type}模板，使用默认字段")
                        self.document_fields[doc_type] = self._get_default_fields(doc_type)
            except Exception as e:
                logger.error(f"❌ 加载模板字段失败: {e}")
                self._init_default_fields()
        else:
            self._init_default_fields()
    
    def _init_default_fields(self):
        """初始化默认字段定义"""
        self.document_fields = {
            'contract': [
                "合同名称", "合同编号", "甲方名称", "甲方地址", "甲方联系人",
                "乙方名称", "乙方地址", "乙方联系人", "合同金额", "履行期限",
                "签署日期", "生效日期", "履行地点", "付款方式", "违约责任"
            ],
            'invoice': [
                "发票代码", "发票号码", "开票日期", "销售方名称", "销售方纳税人识别号",
                "销售方地址电话", "销售方开户行账号", "购买方名称", "购买方纳税人识别号",
                "购买方地址电话", "购买方开户行账号", "货物服务名称", "规格型号", "单位",
                "数量", "单价", "金额", "税率", "税额", "价税合计"
            ],
            'resume': [
                "姓名", "性别", "年龄", "出生日期", "联系电话", "邮箱", "现居地址",
                "籍贯", "学历", "毕业院校", "专业", "毕业时间", "工作经验",
                "当前职位", "期望职位", "期望薪资", "技能特长", "自我评价"
            ],
            'id_card': [
                "姓名", "性别", "民族", "出生日期", "住址", "身份证号码", "签发机关", "有效期限"
            ],
            'medical_report': [
                "患者姓名", "性别", "年龄", "病历号", "检查日期", "检查项目", "检查部位",
                "临床诊断", "检查所见", "检查结论", "建议", "报告医生", "审核医生", "医院名称", "科室"
            ]
        }
    
    def _get_default_fields(self, doc_type: str) -> List[str]:
        """获取指定文档类型的默认字段"""
        return self.document_fields.get(doc_type, [])
    
    def _init_document_templates(self):
        """初始化文档模板数据"""
        # 数据模板
        self.company_names = [
            "北京科技有限公司", "上海贸易股份有限公司", "广州制造企业",
            "深圳创新科技", "杭州软件开发公司", "成都信息技术",
            "南京工程建设", "武汉商贸集团", "西安电子科技",
            "天津港务集团", "重庆物流运输", "青岛海洋工程"
        ]
        
        self.contract_types = [
            "软件开发", "设备采购", "技术服务",
            "咨询服务协议", "维护保养", "租赁服务",
            "供应链", "建设工程", "培训服务"
        ]
        
        self.addresses = [
            "北京市海淀区中关村软件园", "上海市浦东新区张江高科技园",
            "广州市天河区珠江新城", "深圳市南山区科技园",
            "杭州市滨江区物联网街", "成都市高新区天府软件园",
            "南京市江宁区创新大道", "武汉市东湖新技术开发区"
        ]
        
        self.contact_persons = [
            "张经理", "李总监", "王主任", "陈部长",
            "刘经理", "赵总", "孙主管", "周经理"
        ]
        
        # 发票数据模板
        self.invoice_companies = [
            "北京商贸有限公司", "上海制造企业", "广州科技公司",
            "深圳贸易公司", "杭州服务企业", "成都生产厂"
        ]
        
        self.products_services = [
            "软件开发服务", "电子产品", "咨询服务",
            "技术支持", "系统集成", "设备租赁"
        ]
        
        # 简历数据模板
        self.person_names = [
            "张伟", "李明", "王莲", "陈东", "刘芳",
            "赵强", "孙红", "周军", "吴丹", "郑杰"
        ]
        
        self.universities = [
            "北京大学", "清华大学", "上海交大", "复旦大学",
            "浙江大学", "南京大学", "华中科大", "西安交大"
        ]
        
        self.majors = [
            "计算机科学与技术", "软件工程", "电子信息工程",
            "通信工程", "工商管理", "市场营销", "会计学"
        ]
        
        # 医疗报告数据模板
        self.hospitals = [
            "北京协和医院", "上海瑞金医院", "广州中山大学附属第一医院",
            "深圳市人民医院", "杭州市第一人民医院", "成都华西医院"
        ]
        
        self.doctors = [
            "李主任", "王医生", "张教授", "陈副主任",
            "刘医师", "赵主治医师", "孙主任医师", "周医生"
        ]
        
        self.exam_types = [
            "CT检查", "MRI检查", "X光检查", "超声检查",
            "血常规检查", "尿常规检查", "心电图检查"
        ]
    def select_document_type(self) -> str:
        """根据比例选择文档类型"""
        rand = random.random()
        cumulative = 0
        for doc_type, probability in self.document_types.items():
            cumulative += probability
            if rand <= cumulative:
                return doc_type
        return 'contract'  # 默认返回
    
    def generate_document_info(self, doc_type: str = None) -> Dict[str, str]:
        """根据文档类型生成相应信息"""
        if doc_type is None:
            doc_type = self.select_document_type()
        
        if doc_type == 'contract':
            return self.generate_contract_info()
        elif doc_type == 'invoice':
            return self.generate_invoice_info()
        elif doc_type == 'resume':
            return self.generate_resume_info()
        elif doc_type == 'id_card':
            return self.generate_id_card_info()
        elif doc_type == 'medical_report':
            return self.generate_medical_report_info()
        else:
            return self.generate_contract_info()  # 默认生成
    
    def generate_contract_info(self) -> Dict[str, str]:
        """生成合同信息"""
        fields = self.document_fields.get('contract', [])
        if not fields:
            # 回退到原来的实现
            return self._generate_contract_info_legacy()
        
        # 基础信息
        contract_name = random.choice(self.contract_types)
        contract_id = f"HT{random.randint(2023, 2024)}{random.randint(1000, 9999)}"
        
        # 甲乙双方
        party_a = random.choice(self.company_names)
        party_b = random.choice([name for name in self.company_names if name != party_a])
        
        # 金额和期限
        amount = random.randint(10, 1000) * 10000  # 10万到1000万
        duration_months = random.choice([6, 12, 18, 24, 36])
        
        # 日期
        sign_date = datetime.now() - timedelta(days=random.randint(0, 365))
        effective_date = sign_date + timedelta(days=random.randint(1, 30))
        
        # 付款方式
        payment_methods = ["一次性付清", "分期付款", "按月支付", "按阶段支付"]
        
        # 创建字段字典
        info = {}
        for field in fields:
            if field == "合同名称":
                info[field] = contract_name
            elif field == "合同编号":
                info[field] = contract_id
            elif field == "甲方名称":
                info[field] = party_a
            elif field == "甲方地址":
                info[field] = random.choice(self.addresses)
            elif field == "甲方联系人":
                info[field] = random.choice(self.contact_persons)
            elif field == "乙方名称":
                info[field] = party_b
            elif field == "乙方地址":
                info[field] = random.choice(self.addresses)
            elif field == "乙方联系人":
                info[field] = random.choice(self.contact_persons)
            elif field == "合同金额":
                info[field] = f"{amount:,}元"
            elif field == "履行期限":
                info[field] = f"{duration_months}个月"
            elif field == "签署日期":
                info[field] = sign_date.strftime("%Y年%m月%d日")
            elif field == "生效日期":
                info[field] = effective_date.strftime("%Y年%m月%d日")
            elif field == "履行地点":
                info[field] = random.choice(self.addresses)
            elif field == "付款方式":
                info[field] = random.choice(payment_methods)
            elif field == "违约责任":
                info[field] = "按金额的5%承担违约责任"
            else:
                info[field] = "未找到"
        
        return info
    
    def _generate_contract_info_legacy(self) -> Dict[str, str]:
        """生成合同信息（旧版实现）"""
        # 基础信息
        contract_name = random.choice(self.contract_types)
        contract_id = f"HT{random.randint(2023, 2024)}{random.randint(1000, 9999)}"
        
        # 甲乙双方
        party_a = random.choice(self.company_names)
        party_b = random.choice([name for name in self.company_names if name != party_a])
        
        # 金额和期限
        amount = random.randint(10, 1000) * 10000  # 10万到1000万
        duration_months = random.choice([6, 12, 18, 24, 36])
        
        # 日期
        sign_date = datetime.now() - timedelta(days=random.randint(0, 365))
        effective_date = sign_date + timedelta(days=random.randint(1, 30))
        
        # 付款方式
        payment_methods = ["一次性付清", "分期付款", "按月支付", "按阶段支付"]
        
        return {
            "合同名称": contract_name,
            "合同编号": contract_id,
            "甲方名称": party_a,
            "甲方地址": random.choice(self.addresses),
            "甲方联系人": random.choice(self.contact_persons),
            "乙方名称": party_b,
            "乙方地址": random.choice(self.addresses),
            "乙方联系人": random.choice(self.contact_persons),
            "合同金额": f"{amount:,}元",
            "履行期限": f"{duration_months}个月",
            "签署日期": sign_date.strftime("%Y年%m月%d日"),
            "生效日期": effective_date.strftime("%Y年%m月%d日"),
            "履行地点": random.choice(self.addresses),
            "付款方式": random.choice(payment_methods),
            "违约责任": "按金额的5%承担违约责任"
        }
    
    def generate_invoice_info(self) -> Dict[str, str]:
        """生成发票信息"""
        fields = self.document_fields.get('invoice', [])
        if not fields:
            # 回退到原来的实现
            return self._generate_invoice_info_legacy()
        
        # 发票基本信息
        invoice_code = f"{random.randint(1100, 9999)}{random.randint(100000, 999999)}"
        invoice_number = f"{random.randint(10000000, 99999999)}"
        
        # 产品信息
        product = random.choice(self.products_services)
        quantity = random.randint(1, 100)
        unit_price = random.randint(100, 10000)
        amount = quantity * unit_price
        tax_rate = random.choice(["6%", "13%", "17%"])
        tax_amount = amount * (0.06 if tax_rate == "6%" else 0.13 if tax_rate == "13%" else 0.17)
        total_amount = amount + tax_amount
        
        # 日期
        issue_date = datetime.now() - timedelta(days=random.randint(0, 90))
        
        # 创建字段字典
        info = {}
        for field in fields:
            if field == "发票代码":
                info[field] = invoice_code
            elif field == "发票号码":
                info[field] = invoice_number
            elif field == "开票日期":
                info[field] = issue_date.strftime("%Y年%m月%d日")
            elif field == "销售方名称":
                info[field] = random.choice(self.invoice_companies)
            elif field == "销售方纳税人识别号":
                info[field] = f"91{random.randint(100000000000000, 999999999999999)}"
            elif field == "销售方地址电话":
                info[field] = f"{random.choice(self.addresses)} {random.randint(10000000000, 19999999999)}"
            elif field == "购买方名称":
                info[field] = random.choice(self.company_names)
            elif field == "购买方纳税人识别号":
                info[field] = f"91{random.randint(100000000000000, 999999999999999)}"
            elif field == "货物服务名称":
                info[field] = product
            elif field == "单位":
                info[field] = random.choice(["个", "台", "项", "件"])
            elif field == "数量":
                info[field] = str(quantity)
            elif field == "单价":
                info[field] = f"{unit_price:.2f}"
            elif field == "金额":
                info[field] = f"{amount:.2f}元"
            elif field == "税率":
                info[field] = tax_rate
            elif field == "税额":
                info[field] = f"{tax_amount:.2f}元"
            elif field == "价税合计":
                info[field] = f"{total_amount:.2f}元"
            else:
                info[field] = "未找到"
        
        return info
    
    def _generate_invoice_info_legacy(self) -> Dict[str, str]:
        """生成发票信息（旧版实现）"""
        # 发票基本信息
        invoice_code = f"{random.randint(1100, 9999)}{random.randint(100000, 999999)}"
        invoice_number = f"{random.randint(10000000, 99999999)}"
        
        # 产品信息
        product = random.choice(self.products_services)
        quantity = random.randint(1, 100)
        unit_price = random.randint(100, 10000)
        amount = quantity * unit_price
        tax_rate = random.choice(["6%", "13%", "17%"])
        tax_amount = amount * (0.06 if tax_rate == "6%" else 0.13 if tax_rate == "13%" else 0.17)
        total_amount = amount + tax_amount
        
        # 日期
        issue_date = datetime.now() - timedelta(days=random.randint(0, 90))
        
        return {
            "发票代码": invoice_code,
            "发票号码": invoice_number,
            "开票日期": issue_date.strftime("%Y年%m月%d日"),
            "销售方名称": random.choice(self.invoice_companies),
            "销售方纳税人识别号": f"91{random.randint(100000000000000, 999999999999999)}",
            "销售方地址电话": f"{random.choice(self.addresses)} {random.randint(10000000000, 19999999999)}",
            "购买方名称": random.choice(self.company_names),
            "购买方纳税人识别号": f"91{random.randint(100000000000000, 999999999999999)}",
            "货物服务名称": product,
            "单位": random.choice(["个", "台", "项", "件"]),
            "数量": str(quantity),
            "单价": f"{unit_price:.2f}",
            "金额": f"{amount:.2f}元",
            "税率": tax_rate,
            "税额": f"{tax_amount:.2f}元",
            "价税合计": f"{total_amount:.2f}元"
        }
    
    def generate_resume_info(self) -> Dict[str, str]:
        """生成简历信息"""
        fields = self.document_fields.get('resume', [])
        if not fields:
            # 回退到原来的实现
            return self._generate_resume_info_legacy()
        
        # 个人信息
        name = random.choice(self.person_names)
        gender = random.choice(["男", "女"])
        age = random.randint(22, 45)
        birth_year = 2024 - age
        birth_date = f"{birth_year}年{random.randint(1,12)}月{random.randint(1,28)}日"
        
        # 教育背景
        university = random.choice(self.universities)
        major = random.choice(self.majors)
        education = random.choice(["本科", "硕士", "博士"])
        grad_year = random.randint(2015, 2023)
        
        # 工作经验
        work_years = 2024 - grad_year
        current_position = random.choice(["软件工程师", "产品经理", "项目经理", "数据分析师"])
        expected_position = random.choice(["高级软件工程师", "技术主管", "产品总监", "数据科学家"])
        expected_salary = f"{random.randint(15, 50)}K"
        
        # 创建字段字典
        info = {}
        for field in fields:
            if field == "姓名":
                info[field] = name
            elif field == "性别":
                info[field] = gender
            elif field == "年龄":
                info[field] = str(age)
            elif field == "出生日期":
                info[field] = birth_date
            elif field == "联系电话":
                info[field] = f"1{random.randint(3000000000, 8999999999)}"
            elif field == "邮箱":
                info[field] = f"{name.lower()}{random.randint(100,999)}@email.com"
            elif field == "现居地址":
                info[field] = random.choice(self.addresses)
            elif field == "学历":
                info[field] = education
            elif field == "毕业院校":
                info[field] = university
            elif field == "专业":
                info[field] = major
            elif field == "毕业时间":
                info[field] = f"{grad_year}年"
            elif field == "工作经验":
                info[field] = f"{work_years}年"
            elif field == "当前职位":
                info[field] = current_position
            elif field == "期望职位":
                info[field] = expected_position
            elif field == "期望薪资":
                info[field] = expected_salary
            elif field == "技能特长":
                info[field] = "Python, Java, 机器学习, 数据分析"
            elif field == "自我评价":
                info[field] = "具备丰富的项目经验，对技术有激情，具备良好的团队合作能力"
            else:
                info[field] = "未找到"
        
        return info
    
    def _generate_resume_info_legacy(self) -> Dict[str, str]:
        """生成简历信息（旧版实现）"""
        # 个人信息
        name = random.choice(self.person_names)
        gender = random.choice(["男", "女"])
        age = random.randint(22, 45)
        birth_year = 2024 - age
        birth_date = f"{birth_year}年{random.randint(1,12)}月{random.randint(1,28)}日"
        
        # 教育背景
        university = random.choice(self.universities)
        major = random.choice(self.majors)
        education = random.choice(["本科", "硕士", "博士"])
        grad_year = random.randint(2015, 2023)
        
        # 工作经验
        work_years = 2024 - grad_year
        current_position = random.choice(["软件工程师", "产品经理", "项目经理", "数据分析师"])
        expected_position = random.choice(["高级软件工程师", "技术主管", "产品总监", "数据科学家"])
        expected_salary = f"{random.randint(15, 50)}K"
        
        return {
            "姓名": name,
            "性别": gender,
            "年龄": str(age),
            "出生日期": birth_date,
            "联系电话": f"1{random.randint(3000000000, 8999999999)}",
            "邮箱": f"{name.lower()}{random.randint(100,999)}@email.com",
            "现居地址": random.choice(self.addresses),
            "学历": education,
            "毕业院校": university,
            "专业": major,
            "毕业时间": f"{grad_year}年",
            "工作经验": f"{work_years}年",
            "当前职位": current_position,
            "期望职位": expected_position,
            "期望薪资": expected_salary,
            "技能特长": "Python, Java, 机器学习, 数据分析",
            "自我评价": "具备丰富的项目经验，对技术有激情，具备良好的团队合作能力"
        }
    
    def generate_id_card_info(self) -> Dict[str, str]:
        """生成身份证信息"""
        fields = self.document_fields.get('id_card', [])
        if not fields:
            # 回退到原来的实现
            return self._generate_id_card_info_legacy()
        
        name = random.choice(self.person_names)
        gender = random.choice(["男", "女"])
        nation = random.choice(["汉", "回", "蒙古", "藏", "维吾尔", "壮"])
        
        # 生成身份证号码
        birth_year = random.randint(1970, 2005)
        birth_month = random.randint(1, 12)
        birth_day = random.randint(1, 28)
        birth_date = f"{birth_year}年{birth_month:02d}月{birth_day:02d}日"
        
        # 身份证号码结构：6位地区 + 8位生日 + 3位顺序 + 1位校验
        area_code = random.choice(["110101", "310101", "440101", "500101", "330101", "510101"])
        birth_code = f"{birth_year}{birth_month:02d}{birth_day:02d}"
        sequence_code = f"{random.randint(100, 999)}"
        id_number = area_code + birth_code + sequence_code + str(random.randint(0, 9))
        
        # 有效期
        issue_year = random.randint(2010, 2020)
        expire_year = issue_year + random.choice([10, 20])
        validity = f"{issue_year}.{random.randint(1,12):02d}.{random.randint(1,28):02d}-{expire_year}.{random.randint(1,12):02d}.{random.randint(1,28):02d}"
        
        # 创建字段字典
        info = {}
        for field in fields:
            if field == "姓名":
                info[field] = name
            elif field == "性别":
                info[field] = gender
            elif field == "民族":
                info[field] = nation
            elif field == "出生日期":
                info[field] = birth_date
            elif field == "住址":
                info[field] = random.choice(self.addresses)
            elif field == "身份证号码":
                info[field] = id_number
            elif field == "签发机关":
                info[field] = f"{random.choice(['北京市', '上海市', '广州市', '深圳市'])}公安局"
            elif field == "有效期限":
                info[field] = validity
            else:
                info[field] = "未找到"
        
        return info
    
    def _generate_id_card_info_legacy(self) -> Dict[str, str]:
        """生成身份证信息（旧版实现）"""
        name = random.choice(self.person_names)
        gender = random.choice(["男", "女"])
        nation = random.choice(["汉", "回", "蒙古", "藏", "维吾尔", "壮"])
        
        # 生成身份证号码
        birth_year = random.randint(1970, 2005)
        birth_month = random.randint(1, 12)
        birth_day = random.randint(1, 28)
        birth_date = f"{birth_year}年{birth_month:02d}月{birth_day:02d}日"
        
        # 身份证号码结构：6位地区 + 8位生日 + 3位顺序 + 1位校验
        area_code = random.choice(["110101", "310101", "440101", "500101", "330101", "510101"])
        birth_code = f"{birth_year}{birth_month:02d}{birth_day:02d}"
        sequence_code = f"{random.randint(100, 999)}"
        id_number = area_code + birth_code + sequence_code + str(random.randint(0, 9))
        
        # 有效期
        issue_year = random.randint(2010, 2020)
        expire_year = issue_year + random.choice([10, 20])
        validity = f"{issue_year}.{random.randint(1,12):02d}.{random.randint(1,28):02d}-{expire_year}.{random.randint(1,12):02d}.{random.randint(1,28):02d}"
        
        return {
            "姓名": name,
            "性别": gender,
            "民族": nation,
            "出生日期": birth_date,
            "住址": random.choice(self.addresses),
            "身份证号码": id_number,
            "签发机关": f"{random.choice(['北京市', '上海市', '广州市', '深圳市'])}公安局",
            "有效期限": validity
        }
    
    def generate_medical_report_info(self) -> Dict[str, str]:
        """生成医疗报告信息"""
        fields = self.document_fields.get('medical_report', [])
        if not fields:
            # 回退到原来的实现
            return self._generate_medical_report_info_legacy()
        
        patient_name = random.choice(self.person_names)
        gender = random.choice(["男", "女"])
        age = random.randint(20, 80)
        
        # 检查信息
        exam_type = random.choice(self.exam_types)
        exam_date = datetime.now() - timedelta(days=random.randint(1, 30))
        
        # 生成检查结果
        normal_results = [
            "检查结果正常",
            "未见明显异常",
            "在正常范围内"
        ]
        
        abnormal_results = [
            "轻度异常，建议复查",
            "发现轻微变化，建议定期随访",
            "需要进一步检查确认"
        ]
        
        conclusion = random.choice(normal_results + abnormal_results)
        
        # 创建字段字典
        info = {}
        for field in fields:
            if field == "患者姓名":
                info[field] = patient_name
            elif field == "性别":
                info[field] = gender
            elif field == "年龄":
                info[field] = str(age)
            elif field == "病历号":
                info[field] = f"MR{random.randint(100000, 999999)}"
            elif field == "检查日期":
                info[field] = exam_date.strftime("%Y年%m月%d日")
            elif field == "检查项目":
                info[field] = exam_type
            elif field == "检查部位":
                info[field] = random.choice(["胸部", "腹部", "头部", "腰椎", "心脏"])
            elif field == "临床诊断":
                info[field] = random.choice(["健康检查", "病情随访", "疗效评估"])
            elif field == "检查所见":
                info[field] = "各项指标在参考范围内"
            elif field == "检查结论":
                info[field] = conclusion
            elif field == "建议":
                info[field] = "定期复查，注意休息"
            elif field == "报告医生":
                info[field] = random.choice(self.doctors)
            elif field == "审核医生":
                info[field] = random.choice(self.doctors)
            elif field == "医院名称":
                info[field] = random.choice(self.hospitals)
            elif field == "科室":
                info[field] = random.choice(["放射科", "检验科", "心电图室", "超声科"])
            else:
                info[field] = "未找到"
        
        return info
    
    def _generate_medical_report_info_legacy(self) -> Dict[str, str]:
        """生成医疗报告信息（旧版实现）"""
        patient_name = random.choice(self.person_names)
        gender = random.choice(["男", "女"])
        age = random.randint(20, 80)
        
        # 检查信息
        exam_type = random.choice(self.exam_types)
        exam_date = datetime.now() - timedelta(days=random.randint(1, 30))
        
        # 生成检查结果
        normal_results = [
            "检查结果正常",
            "未见明显异常",
            "在正常范围内"
        ]
        
        abnormal_results = [
            "轻度异常，建议复查",
            "发现轻微变化，建议定期随访",
            "需要进一步检查确认"
        ]
        
        conclusion = random.choice(normal_results + abnormal_results)
        
        return {
            "患者姓名": patient_name,
            "性别": gender,
            "年龄": str(age),
            "病历号": f"MR{random.randint(100000, 999999)}",
            "检查日期": exam_date.strftime("%Y年%m月%d日"),
            "检查项目": exam_type,
            "检查部位": random.choice(["胸部", "腹部", "头部", "腰椎", "心脏"]),
            "临床诊断": random.choice(["健康检查", "病情随访", "疗效评估"]),
            "检查所见": "各项指标在参考范围内",
            "检查结论": conclusion,
            "建议": "定期复查，注意休息",
            "报告医生": random.choice(self.doctors),
            "审核医生": random.choice(self.doctors),
            "医院名称": random.choice(self.hospitals),
            "科室": random.choice(["放射科", "检验科", "心电图室", "超声科"])
        }
    
    def _load_font_config(self):
        """加载字体配置"""
        try:
            config_file = "font_config.json"
            if os.path.exists(config_file):
                with open(config_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except Exception as e:
            logger.debug(f"加载字体配置失败: {e}")
        return None
    
    def _setup_default_chinese_font(self) -> bool:
        """设置默认中文字体
        
        Returns:
            是否成功设置中文字体
        """
        try:
            # 尝试创建一个简单的位图字体来显示中文
            # 这是一个fallback方案，当系统没有中文字体时使用
            import urllib.request
            import tempfile
            
            # 尝试下载开源中文字体（如果网络可用）
            font_urls = [
                "https://github.com/adobe-fonts/source-han-sans/releases/download/2.004R/SourceHanSansCN.zip",
                "https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJK-Regular.otf"
            ]
            
            for url in font_urls:
                try:
                    with tempfile.NamedTemporaryFile(delete=False, suffix='.ttf') as tmp_file:
                        urllib.request.urlretrieve(url, tmp_file.name)
                        # 重命名为固定名称
                        os.rename(tmp_file.name, "temp_chinese_font.ttf")
                        logger.info(f"成功下载中文字体: {url}")
                        return True
                except:
                    continue
            
            logger.warning("无法下载中文字体，将使用文本渲染方案")
            return False
            
        except Exception as e:
            logger.debug(f"设置默认字体失败: {e}")
            return False
    
    def create_contract_image(self, contract_info: Dict[str, str], 
                            image_path: str) -> None:
        """创建模拟的图像
        
        Args:
            contract_info: 信息
            image_path: 保存路径
        """
        # 创建画布
        width, height = 800, 1200
        img = Image.new('RGB', (width, height), 'white')
        draw = ImageDraw.Draw(img)
        
        # 尝试使用支持中文的字体
        try:
            title_font = None
            content_font = None
            
            # 优先使用配置文件中的字体
            if self.font_config and self.font_config.get('support_chinese', False):
                font_path = self.font_config['font_path']
                if os.path.exists(font_path):
                    try:
                        title_size = self.font_config.get('title_size', 24)
                        content_size = self.font_config.get('content_size', 16)
                        title_font = ImageFont.truetype(font_path, title_size)
                        content_font = ImageFont.truetype(font_path, content_size)
                        logger.info(f"使用配置字体: {self.font_config['font_name']}")
                    except Exception as e:
                        logger.warning(f"配置字体加载失败: {e}")
            
            # 如果配置字体不可用，扫描系统字体
            if not title_font:
                # 支持中文的字体路径（按优先级排序）
                chinese_font_paths = [
                    # Linux 中文字体
                    "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
                    "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
                    "/usr/share/fonts/truetype/arphic/ukai.ttc",
                    "/usr/share/fonts/truetype/arphic/uming.ttc",
                    "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
                    "/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf",
                    # macOS 中文字体
                    "/System/Library/Fonts/PingFang.ttc",
                    "/System/Library/Fonts/STHeiti Light.ttc",
                    "/System/Library/Fonts/Arial Unicode MS.ttf",
                    # Windows 中文字体
                    "C:/Windows/Fonts/simsun.ttc",
                    "C:/Windows/Fonts/simhei.ttf",
                    "C:/Windows/Fonts/msyh.ttc",
                    "C:/Windows/Fonts/arial.ttf"
                ]
                
                # 尝试加载中文字体
                for font_path in chinese_font_paths:
                    if os.path.exists(font_path):
                        try:
                            title_font = ImageFont.truetype(font_path, 24)
                            content_font = ImageFont.truetype(font_path, 16)
                            logger.info(f"使用系统字体: {font_path}")
                            break
                        except Exception as e:
                            logger.debug(f"字体加载失败 {font_path}: {e}")
                            continue
            
            # 如果仍然找不到字体，使用默认字体并提示
            if not title_font:
                logger.warning("⚠️  未找到中文字体，使用默认字体（可能无法正确显示中文）")
                logger.info("请运行: python scripts/setup_chinese_fonts.py 来检查字体支持")
                
                title_font = ImageFont.load_default()
                content_font = ImageFont.load_default()
                
        except Exception as e:
            logger.error(f"字体设置失败: {e}")
            # 使用默认字体
            title_font = ImageFont.load_default()
            content_font = ImageFont.load_default()
        
        # 绘制标题
        title = contract_info["名称"]
        # 计算标题居中位置（中文字符宽度估算）
        try:
            # 尝试获取文本实际宽度
            bbox = draw.textbbox((0, 0), title, font=title_font)
            text_width = bbox[2] - bbox[0]
            title_x = (width - text_width) // 2
        except:
            # fallback: 估算中文字符宽度
            title_x = width//2 - len(title) * 12
        
        draw.text((title_x, 50), title, fill='black', font=title_font)
        
        # 绘制内容
        y_pos = 120
        line_height = 40  # 增加行高以适应中文
        left_margin = 50
        
        for key, value in contract_info.items():
            text = f"{key}: {value}"
            
            # 优化文本换行处理
            max_chars_per_line = 35  # 每行最大字符数
            
            if len(text) > max_chars_per_line:
                # 智能换行：优先在标点符处切断
                lines = []
                remaining_text = text
                
                while len(remaining_text) > max_chars_per_line:
                    # 在最近的合适位置切断
                    cut_pos = max_chars_per_line
                    for punct in ['、', '，', '。', '；', '：', ' ', ',', '.', ';', ':']:
                        pos = remaining_text.rfind(punct, 0, max_chars_per_line)
                        if pos > max_chars_per_line * 0.7:  # 在后70%的位置找到合适的切断点
                            cut_pos = pos + 1
                            break
                    
                    lines.append(remaining_text[:cut_pos].strip())
                    remaining_text = remaining_text[cut_pos:].strip()
                
                if remaining_text:  # 添加剩余文本
                    lines.append(remaining_text)
                
                # 绘制多行文本
                for line in lines:
                    draw.text((left_margin, y_pos), line, fill='black', font=content_font)
                    y_pos += line_height
            else:
                draw.text((left_margin, y_pos), text, fill='black', font=content_font)
                y_pos += line_height
            
            # 在特定字段后添加额外间距
            if key in ["编号", "乙方联系人", "生效日期"]:
                y_pos += 15
        
        # 添加签名区域
        y_pos += 50
        signature_text1 = "甲方签章:"
        signature_text2 = "乙方签章:"
        
        draw.text((left_margin, y_pos), signature_text1, fill='black', font=content_font)
        draw.text((left_margin + 350, y_pos), signature_text2, fill='black', font=content_font)
        
        # 添加签章框线（模拟）
        box_y = y_pos + 30
        draw.rectangle([left_margin, box_y, left_margin + 120, box_y + 60], outline='gray', width=1)
        draw.rectangle([left_margin + 350, box_y, left_margin + 470, box_y + 60], outline='gray', width=1)
        
        # 添加日期线
        date_y = y_pos + 100
        draw.text((left_margin, date_y), "日期: ____年____月____日", fill='black', font=content_font)
        draw.text((left_margin + 350, date_y), "日期: ____年____月____日", fill='black', font=content_font)
        
        # 保存图像
        img.save(image_path)
        logger.info(f"生成图像: {image_path}")
    
    def create_document_image(self, document_info: Dict[str, str], 
                            image_path: str, doc_type: str) -> None:
        """创建通用文档图像
        
        Args:
            document_info: 文档信息
            image_path: 保存路径
            doc_type: 文档类型
        """
        # 创建画布
        width, height = 800, 1200
        img = Image.new('RGB', (width, height), 'white')
        draw = ImageDraw.Draw(img)
        
        # 设置字体（复用图像的字体设置逻辑）
        try:
            title_font = None
            content_font = None
            
            # 优先使用配置文件中的字体
            if self.font_config and self.font_config.get('support_chinese', False):
                font_path = self.font_config['font_path']
                if os.path.exists(font_path):
                    try:
                        title_size = self.font_config.get('title_size', 24)
                        content_size = self.font_config.get('content_size', 16)
                        title_font = ImageFont.truetype(font_path, title_size)
                        content_font = ImageFont.truetype(font_path, content_size)
                        logger.info(f"使用配置字体: {self.font_config['font_name']}")
                    except Exception as e:
                        logger.warning(f"配置字体加载失败: {e}")
            
            # 如果配置字体不可用，扫描系统字体
            if not title_font:
                chinese_font_paths = [
                    "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
                    "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
                    "/usr/share/fonts/truetype/arphic/ukai.ttc",
                    "/usr/share/fonts/truetype/arphic/uming.ttc",
                    "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
                    "/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf",
                    "/System/Library/Fonts/PingFang.ttc",
                    "/System/Library/Fonts/STHeiti Light.ttc",
                    "C:/Windows/Fonts/simsun.ttc",
                    "C:/Windows/Fonts/simhei.ttf",
                    "C:/Windows/Fonts/msyh.ttc"
                ]
                
                for font_path in chinese_font_paths:
                    if os.path.exists(font_path):
                        try:
                            title_font = ImageFont.truetype(font_path, 24)
                            content_font = ImageFont.truetype(font_path, 16)
                            break
                        except Exception:
                            continue
            
            if not title_font:
                title_font = ImageFont.load_default()
                content_font = ImageFont.load_default()
                
        except Exception as e:
            logger.error(f"字体设置失败: {e}")
            title_font = ImageFont.load_default()
            content_font = ImageFont.load_default()
        
        # 根据文档类型设置标题
        doc_titles = {
            'invoice': '增值税发票',
            'resume': '个人简历',
            'id_card': '中华人民共和国居民身份证',
            'medical_report': '医疗检查报告',
            'contract': '文本'
        }
        
        title = doc_titles.get(doc_type, '文档')
        
        # 计算标题居中位置
        try:
            bbox = draw.textbbox((0, 0), title, font=title_font)
            text_width = bbox[2] - bbox[0]
            title_x = (width - text_width) // 2
        except:
            title_x = width//2 - len(title) * 12
        
        draw.text((title_x, 50), title, fill='black', font=title_font)
        
        # 绘制文档内容
        y_pos = 120
        line_height = 40
        left_margin = 50
        
        for key, value in document_info.items():
            if key in ['image_name', 'sample_id', 'document_type']:  # 跳过元数据字段
                continue
                
            text = f"{key}: {value}"
            
            # 文本换行处理
            max_chars_per_line = 35
            
            if len(text) > max_chars_per_line:
                lines = []
                remaining_text = text
                
                while len(remaining_text) > max_chars_per_line:
                    cut_pos = max_chars_per_line
                    for punct in ['、', '，', '。', '；', '：', ' ', ',', '.', ';', ':']:
                        pos = remaining_text.rfind(punct, 0, max_chars_per_line)
                        if pos > max_chars_per_line * 0.7:
                            cut_pos = pos + 1
                            break
                    
                    lines.append(remaining_text[:cut_pos].strip())
                    remaining_text = remaining_text[cut_pos:].strip()
                
                if remaining_text:
                    lines.append(remaining_text)
                
                for line in lines:
                    draw.text((left_margin, y_pos), line, fill='black', font=content_font)
                    y_pos += line_height
            else:
                draw.text((left_margin, y_pos), text, fill='black', font=content_font)
                y_pos += line_height
            
            # 在特定字段后添加额外间距
            if any(field in key for field in ["编号", "日期", "联系"]):
                y_pos += 15
        
        # 根据文档类型添加特定元素
        if doc_type in ['contract', 'invoice']:
            # 添加签名区域
            y_pos += 50
            if doc_type == 'contract':
                signature_text1 = "甲方签章:"
                signature_text2 = "乙方签章:"
            else:
                signature_text1 = "开票人:"
                signature_text2 = "复核:"
            
            draw.text((left_margin, y_pos), signature_text1, fill='black', font=content_font)
            draw.text((left_margin + 350, y_pos), signature_text2, fill='black', font=content_font)
            
            box_y = y_pos + 30
            draw.rectangle([left_margin, box_y, left_margin + 120, box_y + 60], outline='gray', width=1)
            draw.rectangle([left_margin + 350, box_y, left_margin + 470, box_y + 60], outline='gray', width=1)
        
        elif doc_type == 'id_card':
            # 添加身份证特有元素
            y_pos += 30
            draw.rectangle([width-200, 150, width-50, 250], outline='red', width=2)  # 照片区域
            draw.text((width-150, 200), "照片区域", fill='red', font=content_font)
        
        # 保存图像
        img.save(image_path)
        logger.info(f"生成{doc_type}图像: {image_path}")
    
    def generate_sample_dataset(self, num_samples: int = 50) -> None:
        """生成混合文档类型的示例数据集
        
        Args:
            num_samples: 生成样本数量
        """
        logger.info(f"开始生成 {num_samples} 个混合文档类型示例样本...")
        
        annotations = []
        doc_type_counts = {doc_type: 0 for doc_type in self.document_types.keys()}
        
        for i in range(num_samples):
            # 选择文档类型
            doc_type = self.select_document_type()
            doc_type_counts[doc_type] += 1
            
            # 生成文档信息
            document_info = self.generate_document_info(doc_type)
            
            # 创建图像文件
            image_filename = f"{doc_type}_{i+1:03d}.jpg"
            image_path = self.images_dir / image_filename
            
            try:
                # 根据文档类型创建相应的图像
                if doc_type == 'contract':
                    self.create_contract_image(document_info, str(image_path))
                else:
                    # 其他文档类型使用通用方法创建
                    self.create_document_image(document_info, str(image_path), doc_type)
                
                # 添加到标注数据
                annotation = document_info.copy()
                annotation["image_name"] = image_filename
                annotation["sample_id"] = f"{doc_type}_{i+1:03d}"
                annotation["document_type"] = doc_type  # 添加文档类型标识
                annotations.append(annotation)
                
            except Exception as e:
                logger.error(f"生成第{i+1}个样本失败 ({doc_type}): {e}")
                continue
        
        # 保存标注文件
        annotations_file = self.output_dir / "annotations.json"
        with open(annotations_file, 'w', encoding='utf-8') as f:
            json.dump(annotations, f, ensure_ascii=False, indent=2)
        
        logger.info(f"成功生成 {len(annotations)} 个混合文档样本")
        logger.info(f"文档类型分布: {doc_type_counts}")
        logger.info(f"标注文件保存到: {annotations_file}")
        logger.info(f"图像文件保存到: {self.images_dir}")
        
        return annotations_file
    
    def create_readme(self) -> None:
        """创建数据说明文档"""
        readme_content = """# 通用多模态信息抽取混合数据集

## 数据集说明

本数据集包含模拟生成的多种文档类型图像和对应的标注信息，用于训练Qwen2.5-VL模型进行通用文档信息抽取。

## 支持的文档类型

1. **文档** (25%) - 商业信息抽取
2. **发票文档** (25%) - 增值税发票信息抽取
3. **简历文档** (20%) - 个人简历信息抽取
4. **身份证文档** (15%) - 身份证信息抽取
5. **医疗报告** (15%) - 医疗检查报告信息抽取

## 数据结构

### 图像数据
- 位置：`images/` 目录
- 格式：JPEG图像 (800x1200像素)
- 命名：`{document_type}_{number}.jpg` ，如 `contract_001.jpg`, `invoice_002.jpg`

### 标注数据
- 文件：`annotations.json`
- 格式：JSON数组，每个元素包含一个文档的完整信息
- 特点：每个文档包含 `document_type` 字段标识文档类型

### 字段说明

#### 文档字段
- 名称、编号
- 甲乙双方信息（名称、地址、联系人）
- 条款（金额、期限、日期、付款方式等）

#### 发票文档字段
- 发票代码、发票号码、开票日期
- 销售方和购买方信息
- 商品服务信息和金额税额

#### 简历文档字段
- 个人信息（姓名、性别、年龄、联系方式）
- 教育背景（学历、院校、专业）
- 工作经验和职业信息

#### 身份证文档字段
- 姓名、性别、民族、出生日期
- 住址、身份证号码
- 签发机关、有效期限

#### 医疗报告字段
- 患者信息（姓名、性别、年龄、病历号）
- 检查信息（日期、项目、部位、诊断）
- 检查结果和医疗人员信息

## 数据使用

1. 使用 `data_processor.py` 将标注数据转换为Swift训练格式
2. 数据会自动分割为训练集和验证集
3. 支持数据质量验证和错误检查
4. 支持混合数据集训练，不区分文档类型

## 混合训练特点

- **动态字段识别**：模型学会自动识别不同文档类型中的相关字段
- **通用信息抽取**：不需要预先知道文档类型，直接进行信息抽取
- **跨领域适应性**：单个模型能够处理多种不同类型的文档
- **更好的泛化能力**：通过混合训练提高模型的鲁棒性

## 注意事项

- 本数据集为模拟数据，仅用于技术验证和学习
- 实际应用中请使用真实的文档数据
- 建议根据具体业务需求调整字段定义
- 混合数据集训练需要较大的数据量才能获得最佳效果
"""
        
        readme_file = self.output_dir / "README_DATA.md"
        with open(readme_file, 'w', encoding='utf-8') as f:
            f.write(readme_content)
        
        logger.info(f"数据说明文档已保存: {readme_file}")


def main():
    """主函数"""
    generator = MixedDocumentGenerator()
    
    # 生成混合文档类型的示例数据集
    annotations_file = generator.generate_sample_dataset(num_samples=30)
    
    # 创建说明文档
    generator.create_readme()
    
    # 转换为Swift格式
    logger.info("转换数据格式...")
    
    # 使用通用数据处理器
    try:
        from data_processor import UniversalDocumentProcessor
        processor = UniversalDocumentProcessor()
    except ImportError:
        # 向后兼容：如果旧的导入不可用，尝试新的
        try:
            from data_processor import ContractDataProcessor as UniversalDocumentProcessor
            processor = UniversalDocumentProcessor()
        except ImportError:
            logger.error("无法导入数据处理器，请检查data_processor.py文件")
            return
    
    swift_data_file = "data/train_data.jsonl"
    processor.convert_annotations_to_swift_format(
        str(annotations_file), 
        swift_data_file
    )
    
    # 验证数据
    is_valid, errors = processor.validate_data(swift_data_file)
    if is_valid:
        logger.info("数据验证通过")
        # 分割数据集
        train_file, eval_file = processor.split_dataset(swift_data_file, train_ratio=0.8)
        logger.info(f"训练数据: {train_file}")
        logger.info(f"验证数据: {eval_file}")
    else:
        logger.error("数据验证失败:")
        for error in errors[:5]:  # 只显示前5个错误
            logger.error(f"  - {error}")


# 向后兼容性别名
SampleDataGenerator = MixedDocumentGenerator


if __name__ == "__main__":
    main()